/**
 *  Copyright (C) 2006 zhangbo (freeeob@gmail.com)
 *
 *  This product is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as published by
 *  the Free Software Foundation; either version 2.1 of the License, or
 *  (at your option) any later version.
 * 
 *  This product is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Lesser General Public License for more details.
 * 
 *  You should have received a copy of the GNU Lesser General Public License
 *  along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA.
 *
 *  author:zhangbo
 *  Email:jsjava@gmail.com
 */

/**
 * Constructor
 */ 
function EventUtils(){
	this.jsjava_class="jsorg.eob.event.EventUtils";
}

/**
 * Add event to given dom object
 * @param domObj object in document model
 * @param eventName event name such as onclick
 * @param funcName javascript function
 * @param isBroadcase
 */
EventUtils.addDomEvent=function(domObj, eventName, funcName, isBroadcast){
	if(eventName.indexOf("on")==0){
		eventName=eventName.substring(2);
	}
	if (domObj.addEventListener) {
		domObj.addEventListener(eventName, funcName, isBroadcast);
		return true;
	} else if (domObj.attachEvent) {
		return domObj.attachEvent("on" + eventName, funcName);
	}
	else {
		element['on' + eventName] = funcName;
	}	
};

/**
 * Add event on window load
 * @param funcName javascript function
 */
EventUtils.addEventOnWindowLoad=function(funcName){
	EventUtils.addDomEvent(window,"onload",funcName,false);
};

/**
 * Add event on window unload
 * @param funcName javascript function
 */
EventUtils.addEventOnWindowUnLoad=function(funcName){
	EventUtils.addDomEvent(window,"onunload",funcName,false);
};

/**
 * remove event from given dom object
 * @param domObj object in document model
 * @param eventName event name such as onclick
 * @param funcName javascript function
 * @param isBroadcase
 */
EventUtils.removeDomEvent=function(domObj, eventName, funcName,isBroadcast){
	if(eventName.indexOf("on")==0){
		eventName=eventName.substring(2);
	}
	if (domObj.removeEventListener) {
		domObj.removeEventListener(eventName, funcName,isBroadcast);
		return true;
	} else if (domObj.detachEvent) {
		return domObj.detachEvent("on" + eventName, funcName);
	}
	else {
		element['on' + eventName] = null;
	}	
};

/**
 * Check whether the current mouse click is left click
 * @param event the current window event
 */
EventUtils.isLeftClick=function(event){
	return event.which==1||event.button==0;
};

/**
 * Get the event soruce object
 * @param event the current window event
 */
EventUtils.getEventSource=function(event){
	return event.srcElement||event.target;
};

/**
 * This function is responsible for format the event to DOM Standard Event
 * Mainly For Format the IE's Event Model
 */
EventUtils.formatEvent = function (oEvent) {
    if (BrowserUtils.isIE() && OSUtils.isWindows()) {
        oEvent.charCode = (oEvent.type == "keypress") ? oEvent.keyCode : 0;
        oEvent.eventPhase = 2;
        oEvent.isChar = (oEvent.charCode > 0);
        oEvent.pageX = oEvent.clientX + document.body.scrollLeft;
        oEvent.pageY = oEvent.clientY + document.body.scrollTop;
        oEvent.preventDefault = function () {
            this.returnValue = false;
        };
        if (oEvent.type == "mouseout") {
            oEvent.relatedTarget = oEvent.toElement;
        } else if (oEvent.type == "mouseover") {
            oEvent.relatedTarget = oEvent.fromElement;
        }
        oEvent.stopPropagation = function () {
            this.cancelBubble = true;
        };
        oEvent.target = oEvent.srcElement;
        oEvent.time = (new Date).getTime();
    } else {
    	oEvent.srcElement = oEvent.target;
    }
    return oEvent;
};

/**
 * Get the event object
 */
EventUtils.getEvent=function(){
	if (BrowserUtils.isIE()) {
        return EventUtils.formatEvent(window.event);
    } else {
    	var caller_func = arguments.callee.caller;
    	while(caller_func != null) {
			var caller_arg0 = caller_func.arguments[0];
			if (caller_arg0) {
				if(caller_arg0.constructor==Event || caller_arg0.constructor == MouseEvent || caller_arg0.constructor == KeyboardEvent) {
					return this.formatEvent(caller_arg0);
				}
			}
			caller_func = caller_func.caller;
		}
		return null;
    }
};

/**
 * Get the mouse position
 * @param event the current mouse event
 */
EventUtils.getMousePosition=function(event){
	 var x=event.clientX;
     var y=event.clientY;
     var scrollX=x+document.body.scrollLeft;
     var scrollY=y+document.body.scrollTop;
     return [scrollX,scrollY];
};

/**
 * Get the suitable showing position on mouse click
 * @param event the current mouse event
 * @param floatObj
 */
EventUtils.getFloatShowPosition=function(event,floatObj){
	 var clientX=event.clientX;
     var clientY=event.clientY;
     var scrollX=clientX+document.body.scrollLeft;
     var scrollY=clientY+document.body.scrollTop;
     var floatRect=DocumentUtils.getElementRectangle(floatObj);
     var fX=floatRect.left;
	 var fY=floatRect.top;
	 var fWidth=floatRect.right-floatRect.left;
	 var fHeight=floatRect.bottom-floatRect.top;
	 if(document.body.clientWidth-clientX<fWidth){
          scrollX=scrollX-fWidth;
     }
     if(document.body.clientHeight-clientY<fHeight){
         scrollY=scrollY-fHeight;
     }
     return [scrollX,scrollY];
};

/**
 * Show float object in suitable position on mouse click
 * @param event the current mouse event
 * @param floatObj
 */
EventUtils.showFloatInPosition=function(event,floatObj){
	var arr=EventUtils.getFloatShowPosition(event,floatObj);
	floatObj.style.left=arr[0];
	floatObj.style.top=arr[1];
};

/**
 * Set the mouse event capture
 * @param elem
 */
EventUtils.setCapture=function(elem){
	if(BrowserUtils.isIE()) {
		elem.setCapture();
	} else if(BrowserUtils.isFirefox()) {
		window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
	}else{
	
	}
};

/**
 * Release the mouse event capture
 * @param elem
 */
EventUtils.releaseCapture=function(elem){
	if(BrowserUtils.isIE()) {
		elem.releaseCapture();
	} else if(BrowserUtils.isFirefox()) {
		window.captureEvents(Event.MOUSEMOVE|Event.MOUSEUP);
	}else{
	
	}
};

/**
 * Stop the event to propagate
 * @param elem
 */
EventUtils.stopPropagation=function(){
	var e=EventUtils.getEvent();
	if(e.stopPropagation){
		e.stopPropagation();
	}else{
		e.cancelBubble=true;
	}
};

/**
 * Stop the event to propagate
 * @param elem
 */
EventUtils.preventDefault=function(){
	var e=EventUtils.getEvent();
	if(event.preventDefault){
		e.preventDefault();
	}else{
		e.returnValue=false;
	}
};

/**
 * Set Ctrl Mnemonic on the keyboard
 * @param domObj
 * @param keyChar
 * @param func
 * @param isBroadcast
 */
EventUtils.setCtrlMnemonic=function(domObj,keyChar,func,isBroadcast){
	if(!domObj){
		throw new NullPointerException("The parameter domObj is null");
	}
	if(StringUtils.isBlank(isBroadcast)){
		isBroadcast=true;
	}
	EventUtils.addDomEvent(domObj,"keydown",new Function("if(EventUtils.isCtrlKey()&&EventUtils.isSpecifiedKey('"+keyChar+"')){if(!"+isBroadcast+"){EventUtils.stopPropagation();EventUtils.preventDefault();}}"),false);
	EventUtils.addDomEvent(domObj,"onkeyup",new Function("if(EventUtils.isCtrlKey()&&EventUtils.isSpecifiedKey('"+keyChar+"')){eval('"+func+"()');}"),false);
};

/**
 * Set Alt Mnemonic on the keyboard
 * @param domObj
 * @param keyChar
 * @param func
 * @param isBroadcast
 */
EventUtils.setAltMnemonic=function(domObj,keyChar,func,isBroadcast){
	if(!domObj){
		throw new NullPointerException("The parameter domObj is null");
	}
	if(StringUtils.isBlank(isBroadcast)){
		isBroadcast=true;
	}
	EventUtils.addDomEvent(domObj,"keydown",new Function("if(EventUtils.isAltKey()&&EventUtils.isSpecifiedKey('"+keyChar+"')){if(!"+isBroadcast+"){EventUtils.stopPropagation();EventUtils.preventDefault();}}"),false);
	EventUtils.addDomEvent(domObj,"onkeyup",new Function("if(EventUtils.isAltKey()&&EventUtils.isSpecifiedKey('"+keyChar+"')){eval('"+func+"()');}"),false);
};

/**
 * Set Shift Mnemonic on the keyboard
 * @param domObj
 * @param keyChar
 * @param func
 * @param isBroadcast
 */
EventUtils.setShiftMnemonic=function(domObj,keyChar,func,isBroadcast){
	if(!domObj){
		throw new NullPointerException("The parameter domObj is null");
	}
	if(StringUtils.isBlank(isBroadcast)){
		isBroadcast=true;
	}
	EventUtils.addDomEvent(domObj,"keydown",new Function("if(EventUtils.isShiftKey()&&EventUtils.isSpecifiedKey('"+keyChar+"')){if(!"+isBroadcast+"){EventUtils.stopPropagation();EventUtils.preventDefault();}}"),false);
	EventUtils.addDomEvent(domObj,"onkeyup",new Function("if(EventUtils.isShiftKey()&&EventUtils.isSpecifiedKey('"+keyChar+"')){eval('"+func+"()');}"),false);
};

/**
 * Judge wether the space key is pressed
 */
EventUtils.isSpaceKey=function(){
	return KeyUtils.isSpaceKey(EventUtils.getKeyCode());
};

/**
 * Judge wether the enter key is pressed
 */
EventUtils.isEnterKey=function(){
	return KeyUtils.isEnterKey(EventUtils.getKeyCode());
};

/**
 * Judge wether the ESC key is pressed
 */
EventUtils.isESCKey=function(){
	return KeyUtils.isESCKey(EventUtils.getKeyCode());
};

/**
 * Judge wether the specified key is pressed
 */
EventUtils.isSpecifiedKey=function(char){
	return char.toUpperCase()==KeyUtils.fromCharCode(EventUtils.getKeyCode());
};

/**
 * Judge wether the Ctrl key is pressed
 */
EventUtils.isCtrlKey=function(){
	var e=EventUtils.getEvent();
	return e.ctrlKey;
};

/**
 * Judge wether the Shift key is pressed
 */
EventUtils.isShiftKey=function(){
	var e=EventUtils.getEvent();
	return e.ShiftKey;
};

/**
 * Judge wether the Alt key is pressed
 */
EventUtils.isAltKey=function(){
	var e=EventUtils.getEvent();
	return e.altKey;
};

/**
 * Get number value of the key pressed
 */
EventUtils.getKeyCode=function(){
	var e=EventUtils.getEvent();
	if(BrowserUtils.isIE()){
		return e.keyCode;
	}else{
		return e.which;
	}
};

/**
 * Set current cursor to next input on enter event
 * @param domObj
 */
EventUtils.setCursorToNextOnEnter=function(domObj){
	EventUtils.addDomEvent(domObj,"keydown",new Function("if(EventUtils.isEnterKey()){var e=EventUtils.getEvent();e.keyCode=9;}"),false);
};